interface User {
    name:string,
    age:number,
    //sayhellow:() => void    //返回类型
    sayhellow():void
    
}


//类型别名的写法

// type User = {
//     name:string,
//     age:number
//     sayhellow():void
// }




let user:User = {
     name:"DDWEE",
     age:18,
     //接口约束函数(约束对像里面的函数)
     sayhellow() {
         console.log(9999)
     }
}





//type Conditon = (n:number) => boolean
// type Conditon = {  //大括号表示一个定界符，里面的东西表示的是内容
//     (n:number): boolean
// }
//约束的一个普通函数
// interface Conditon {  //大括号表示一个定界符，里面的东西表示的是内容
//     //小括号是一个匿名函数，表示内容
//     (n:number): boolean
// }
// function sum(number:number[], calback:Conditon):number {
//   let s = 0
//   number.forEach(n => {
//       if(calback(n)) {
//           s += n
//       }
//   })
//   return s
// }



// console.log(sum([1,20,6,3,4],(n)=> n % 2 !== 0),9999)


//接口可以继承
interface A {
    t1:string
}

interface B extends A {
    t1:string,
    t2:number
}

let u:B = {
    t1:'sssss',

    t2:2222
}


interface D {
    t4:number
}
interface C extends A, D{
    t3:boolean
}

let n:C = {
    t1:'111',
    t3:false,
    t4:12333

}


//----------------------readonly----------------------

// interface Users {
//     readonly id:string,
//     name:string,
//     age:number
// }


// let someOne:Users = {
//     id:"1111",
//     name:"d24f3",
//     age:19
// }
//someOne.id = 'qqq'  //不可以更改，只读修饰符不参与编译

let arr:readonly number[] = [11,22,33,44]
//arr.push  变成一个只读的数组后，不可以用数组的方法，push，splice等，并且单个的arr【1】= 111,不可以被赋值


//---------------------------------》 类型兼容 《-------------------------------
    //b -> a 如果能完成赋值，则b和a类型兼容
    //鸭子辨型法（子结构变型法）：目标类型需要某一些特征，赋值的类型只要满足该特征即可以

    //基本类型：完全匹配
    //对象：鸭子变型法，满足特征

    // interface Duck {
    //     sound:"嘎嘎嘎嘎"
    //     swing():void
    // }

    // //类型断言

    // let pers = {
    //     name:"伪装成鸭子",
    //     age:11,
    //     sound:"嘎嘎嘎嘎" as "嘎嘎嘎嘎",//类型断言  ----------》前面是数据，一个为string的数据，后面是数据类型
    //     swing() {
    //         console.log(this.name + '正在游泳，并且发出了' + this.sound + '的声音')
    //     }
    // }
    
    // //这个人满足Duck的特征
    // let duck:Duck = pers


    //假设有一个函数，用于得到服务器的某个接口的返回结果，是一个用户的对像，这个对象有100个属性，但是用到的数据很少

    let resu = {
        loginId:'erwfr',
        nickName:"dfswerg",
        sex:"男",
        age:30,
        qq:3644576
    } 
    interface ResponseUser {
        loginId:string
        nickName:string
        age:number
    }

   let resuser:ResponseUser = resu
   
//当使用子面量


// --------------------当直接受用对象字面量赋值时会进行更加严格的判断
// interface Duck {
//     sound:"嘎嘎嘎嘎"
//     swing():void
// }
// let pers:Duck = {
//     name:"伪装成鸭子",
//     age:11,
//     sound:"嘎嘎嘎嘎" as "嘎嘎嘎嘎",//类型断言  ----------》前面是数据，一个为string的数据，后面是数据类型
//     swing() {
//         console.log(this.name + '正在游泳，并且发出了' + this.sound + '的声音')
//     }
// }



interface SpeUser {
    name?:string,  //可以不写
    age:number
}
let kai:SpeUser = {
    age:14
}




//----------------------》 函数 《-----------------
//对象用的数鸭子类型法
//函数怎么判定的
      //1、函数的参数, 传递给目标函数的参数可以少，不可以多，但是类型必须符合；
      //2、返回值  必须要求返回的东西就必须返回，类型匹配，  不要求返回的时候，你随意
interface Conditon {  //大括号表示一个定界符，里面的东西表示的是内容
    //小括号是一个匿名函数，表示内容
    (n:number, i:number): boolean
}
function sum(number:number[], calback:Conditon):number {
  let s = 0
  number.forEach((n,i) => {
      if(calback(n,i)) {
          s += n
      }
  })
  return s
}



console.log(sum([1,20,6,3,4],(n)=> n % 2 !== 0),9999)   //回调函数约束有两个参数
